﻿using System;
using System.Collections.Generic;
using System.Text;
using Rage.Base.Abilities;

namespace Rage.Juggernaut
{
    public class CharacterCalculationsJuggernaut : CharacterCalculationsBase
    {
        public Base.StatsWarrior AverageStats { get; set; }
        public Base.StatsWarrior MaximumStats { get; set; }
        public Base.StatsWarrior UnbuffedStats { get; set; }
        public Base.StatsWarrior BuffedStats { get; set; }
        public Base.StatsWarrior BuffsStats { get; set; } // The actual stats that come from Buffs
        public CombatFactors CombatFactors { get; set; }
        public Rotation Rot { get; set; }
        public DefendModel DefendModel { get; set; }
        public List<AbilityWrapper> Abilities { get; set; }

        #region Points
        public override float OverallPoints { get { return (_subPoints[0] + _subPoints[1] + _subPoints[2] + _subPoints[3]); } set { } }

        private float[] _subPoints = new float[] { 0f, 0f, 0f, 0f };
        public override float[] SubPoints
        {
            get { return _subPoints; }
            set { _subPoints = value; }
        }
        public float SurvivalPoints   { get { return _subPoints[0]; } set { _subPoints[0] = Math.Min(value, float.MaxValue); } }
        public float MitigationPoints { get { return _subPoints[1]; } set { _subPoints[1] = Math.Min(value, float.MaxValue); } }
        public float DPSPoints        { get { return _subPoints[2]; } set { _subPoints[2] = Math.Min(value, float.MaxValue); } }
        public float ThreatPoints     { get { return _subPoints[3]; } set { _subPoints[3] = Math.Min(value, float.MaxValue); } }
        #endregion

        public float OtherResourceO20 { get; set; }
        public float NeedyResourceO20 { get; set; }
        public float FreeResourceO20 { get; set; }
        public float OtherResourceU20 { get; set; }
        public float NeedyResourceU20 { get; set; }
        public float FreeResourceU20 { get; set; }

        public float TotalDPS { get; set; }
        public float TotalTPS { get; set; }
        public float TotalHPS { get; set; }
        public string ThreatModel { get; set; }
        public string ThreatModelName { get; set; }

        public int RankingMode { get; set; }
        public float TankPoints { get; set; }
        public float BurstTime { get; set; }
        public float ThreatScale { get; set; }

        public float Duration { get; set; }
        public bool PTRMode { get; set; }

        public float BaseHealth { get; set; }

        #region Attack Table
        public float Miss { get; set; }
        public float AccuracyRating { get; set; }
        public float AgilityCritBonus { get; set; }
        public float CritRating { get; set; }
        public float CritPercent { get; set; }
        public float MHCrit { get; set; }
        public float OHCrit { get; set; }
        #endregion
        public float DefenseFromTalentsAndBuffs { get; set; }
        public float ShieldFromTalentsAndBuffs { get; set; }
        public float ShieldFromGenerator { get; set; }
        public float AbsorbFromGenerator { get; set; }
        public float Defense { get; set; }
        public float Dodge { get; set; }
        public float Parry { get; set; }
        public float Shield { get; set; }
        public float Absorb { get; set; }
        public float CritVulnerability { get; set; }
        public float ArmorReduction { get; set; }
        public float GuaranteedReduction { get; set; }
        public float AnyMiss { get; set; }
        public float AnyAvoid { get; set; }
        public float BaseAnyAvoid { get; set; }
        public float BuffedAnyAvoid { get; set; }
        public float TotalMitigation { get; set; }
        public float DamageTaken { get; set; }
        public float DamageTakenPerHit { get; set; }
        public float DamageTakenPerShield { get; set; }
        public float DamageTakenPerCrit { get; set; }

        // Special Damage (Shadow, Fire, etc)
        public float SpecProcDPS { get; set; }
        public float SpecProcDmgPerHit { get; set; }
        public float SpecProcActs { get; set; }

        public float KineticReduction { get; set; }
        public float EnergyReduction { get; set; }
        public float InternalReduction { get; set; }
        public float ElementalReduction { get; set; }
        public float KineticSurvivalPoints { get; set; }
        public float EnergySurvivalPoints { get; set; }
        public float InternalSurvivalPoints { get; set; }
        public float ElementalSurvivalPoints { get; set; }

        public float MissedAttacks { get; set; }
        public float AvoidedAttacks { get; set; }
        public float DodgedAttacks { get; set; }
        public float ParriedAttacks { get; set; }
        public float ShieldedAttacks { get; set; }
        public float Accuracy { get; set; }
        public float Crit { get; set; }
        public float AlacrityRating { get; set; }
        public float AlacrityPercent { get; set; }

        public override Dictionary<string, string> GetCharacterDisplayCalculationValues()
        {
            Dictionary<string, string> dictValues = new Dictionary<string, string>();

            #region Basic Stats
            { // Strength
                string statement = string.Format("{0:#,##0.##}", AverageStats.Strength);
                string tooltip = string.Format("Strength {0:#,##0.##}"
                    +                       "*Base: {1:#,##0.##} Bonus: {2:#,##0.##}"
                    + Environment.NewLine + "Melee Damage Bonus: +{3:#,##0.##}"
                    + Environment.NewLine + "Melee Critical Chance: +{4:0.##%}"
                    + Environment.NewLine + "Force Damage Bonus: +{5:#,##0.##}"
                    + Environment.NewLine + "Force Critical Chance: +{6:0.##%}"
                    +                       "*Strength increases your aptitude in melee combat."
                    ,
                    AverageStats.Strength,
                    250f, BuffedStats.Strength - 250f,
                    AverageStats.Strength * 0.20f,
                    StatConversion.GetCritFromMainStat(AverageStats.Strength),
                    AverageStats.Strength * 0.20f,
                    StatConversion.GetCritFromMainStat(AverageStats.Strength)
                    );
                dictValues["Strength"] = statement + "*" + tooltip;
            }
            dictValues["Presence"] = AverageStats.Presence.ToString();
            { // Endurance
                string statement = string.Format("{0:#,##0.##}", AverageStats.Endurance);
                string tooltip = string.Format("Endurance {0:#,##0.##}"
                    +                       "*Base: {1:#,##0.##} Bonus: {2:#,##0.##}"
                    + Environment.NewLine + "Max Health: +{3:#,##0.##}"
                    + Environment.NewLine + "Health Regen: +{4:0.##}"
                    +                       "*Endurance increases the amount of damage you can"
                    + Environment.NewLine + "suffer before being defeated."
                    ,
                    AverageStats.Endurance,
                    225f, BuffedStats.Endurance - 225f,
                    StatConversion.GetHealthFromEndurance(AverageStats.Endurance),
                    StatConversion.GetHealthRegenFromEndurance(AverageStats.Endurance)
                    );
                dictValues["Endurance"] = statement + "*" + tooltip;
            }
            { // Health
                string statement = string.Format("{0:#,##0.##}", AverageStats.Health);
                string tooltip = string.Format("Health: {0:#,##0.##}"
                    +                       "*Base: {1:#,##0.##}"
                    + Environment.NewLine + "Bonus: {2:#,##0.##}"
                    + Environment.NewLine + "    Endurance ({3:#,##0.##}): +{2:#,##0.##}"
                    + Environment.NewLine
                    +                       "*Amount of damage you can suffer before being"
                    + Environment.NewLine + "defeated."
                    ,
                    AverageStats.Health,
                    2500f, AverageStats.Health - 2500f,
                    (AverageStats.Health - 2500f) / 10f
                    );
                dictValues["Health"] = statement + "*" + tooltip;
            }
            #endregion
            #region Defensive Attack Table
            dictValues["Dodge Chance"] = string.Format("{0:0.00%}*Defense Chance {1:#0.##%} / 2", Dodge, AverageStats.Defense);
            dictValues["Parry Chance"] = string.Format("{0:0.00%}*Defense Chance {1:#0.##%} / 2", Parry, AverageStats.Defense);
            dictValues["Miss Chance"] = string.Format("{0:0.00%}*Target has no accuracy, so {0:0.00%} chance to miss", Miss);
            { // Shield Chance
                string statement = string.Format("{0:#0.##%}", Shield);
                string tooltip = string.Format("Shield Chance: {0:#0.##%}"
                    +                       "*Shield Generator: {1:#0.##%}"
                    + Environment.NewLine + "Bonus: {2:#0.##%}"
                    + Environment.NewLine + "    Shield Rating ({3:#,##0.##}): +{4:#0.##%}"
                    + Environment.NewLine + "    Skills/Buffs: +{5:#0.##%}"
                    +                      "*Chance that a successful melee or ranged attack"
                    + Environment.NewLine + "will have its damage reduced by your shield."
                    ,
                    Shield,
                    ShieldFromGenerator,
                    Shield - ShieldFromGenerator,
                    AverageStats.ShieldRating, StatConversion.GetShieldFromRating(AverageStats.ShieldRating),
                    ShieldFromTalentsAndBuffs
                    );
                dictValues["Shield Chance"] = statement + "*" + tooltip;
            }
            dictValues["Crit Chance"] = string.Format("{0:0.00%}", CritVulnerability);
            dictValues["Hit Chance"] = string.Format("{0:0.00%}",
                Math.Max(0f, 1f - Dodge - Parry - Miss - Shield - CritVulnerability));
            #endregion
            #region Defensive Stats
            { // Armor
                string statement = string.Format("{0:#,##0.##}", AverageStats.Armor);
                string tooltip = string.Format("Armor: {0:#,##0.##}"
                    +                       "*Armor Damage Reduction: +{1:#0.##%}"
                    + Environment.NewLine + "    (vs. attacker of the same level)"
                    +                       "*Armor reduces the amount of damage suffered"
                    + Environment.NewLine + "from kinetic and energy attacks."
                    ,
                    AverageStats.Armor,
                    StatConversion.GetArmorDamageReduction(AverageStats.Armor, 0, 0)
                    );
                dictValues["Armor"] = statement + "*" + tooltip;
            }
            { // Defense Chance
                string statement = string.Format("{0:#0.##%}", AverageStats.Defense);
                string tooltip = string.Format("Defense Chance:"
                    +                       "*Melee Parry: {0:#0.##%}"
                    + Environment.NewLine + "    Base: {1:#0.##%}"
                    + Environment.NewLine + "    Defense Rating ({2:#,##0.##}): +{3:#0.##%}"
                    + Environment.NewLine + "    Skills/Buffs: +{4:#0.##%}"
                    + Environment.NewLine + "Ranged Deflect: {0:#0.##%}"
                    + Environment.NewLine + "    Base: {1:#0.##%}"
                    + Environment.NewLine + "    Defense Rating ({2:#,##0.##}): +{3:#0.##%}"
                    + Environment.NewLine + "    Skills/Buffs: +{4:#0.##%}"
                    + Environment.NewLine + "Resistance: {5:#0.##%}"
                    + Environment.NewLine + "Resistance: {6:#0.##%}"
                    +                       "*Chance to avoid incoming attacks, broken down by"
                    + Environment.NewLine + "attack type."
                    ,
                    AverageStats.Defense,
                    0.05f, AverageStats.DefenseRating, StatConversion.GetDefenseFromRating(AverageStats.DefenseRating) - 0.05f,
                    DefenseFromTalentsAndBuffs,
                    AverageStats.InternalResistance, AverageStats.ElementalResistance
                    );
                dictValues["Defense Chance"] = statement + "*" + tooltip;
            }
            { // Shield Absorption
                string statement = string.Format("{0:#0.##%}", Absorb);
                string tooltip = string.Format("Shield Absorption: {0:#0.##%}"
                    +                       "*Shield Generator: {1:#0.##%}"
                    + Environment.NewLine + "Bonus: {2:#0.##%}"
                    + Environment.NewLine + "    Absorption Rating ({3:#,##0.##}): +{4:#0.##%}"
                    +                       "*Percentage of damage lost when an attack is"
                    + Environment.NewLine + "absorbed by your shield."
                    ,
                    Absorb,
                    AbsorbFromGenerator,
                    Absorb - AbsorbFromGenerator,
                    AverageStats.AbsorbRating, StatConversion.GetAbsorbFromRating(AverageStats.AbsorbRating)
                    );
                dictValues["Shield Absorption"] = statement + "*" + tooltip;
            }
            // TODO: Below area
            dictValues["Guaranteed Reduction"] = string.Format("{0:0.00%}", GuaranteedReduction);

            if (AnyAvoid != BaseAnyAvoid)
                dictValues["Avoidance"] = string.Format("{0:0.00%}*Avoidance: {0:0.00%}" + Environment.NewLine +
                                                            "+ Normal Shield Chance: {1:0.00%}" + Environment.NewLine +
                                                            "+ Average Shield Chance: {2:0.00%}" + Environment.NewLine +
                                                            "+ Shield Chance w/ Shield Shield: {3:0.00%}", AnyMiss, BaseAnyAvoid, AnyAvoid, BuffedAnyAvoid);
            else
                dictValues["Avoidance"] = string.Format("{0:0.00%}*Avoidance: {0:0.00%}" + Environment.NewLine +
                                                           "Avoidance + Shield: {1:0.00%}", AnyMiss, BaseAnyAvoid);

            dictValues["Total Mitigation"] = string.Format("{0:0.00%}", TotalMitigation);

            dictValues["Damage Taken"] = string.Format("{0:0.0} DPS*{1:0} damage per normal attack" +
                                 Environment.NewLine + "{2:0} damage per shielded attack" +
                                 Environment.NewLine + "{3:0} damage per critical attack",
                                 DamageTaken,
                                 DamageTakenPerHit,
                                 DamageTakenPerShield,
                                 DamageTakenPerCrit);
            #endregion
            #region Offensive Attack Table
            dictValues["Chance to be Dodged"] = string.Format("{0:0.00%}", DodgedAttacks);
            dictValues["Chance to be Parried"] = string.Format("{0:0.00%}", ParriedAttacks);
            dictValues["Chance to Miss"] = string.Format("{0:0.00%}", MissedAttacks);
            dictValues["Chance to be Shielded"] = string.Format("{0:0.00%}*TODO: Verify target's can't shield", 0f);
            { // Strength
                string statement = string.Format("{0:#0.##%} / {1:#0.##%}",
                    AverageStats.BonusCritChance + AverageStats.BonusBasicCritChance,
                    AverageStats.BonusCritChance + AverageStats.BonusForceCritChance);
                string tooltip = string.Format("Melee Chance to Crit {0:#0.##%}"
                    +                       "*Base: {1:#0.##%}"
                    + Environment.NewLine + "Bonus: {2:#0.##%}"
                    + Environment.NewLine + "    Strength ({3:#,##0.##}): +{4:#0.##%}"
                    + Environment.NewLine + "    Critical Rating ({5:#,##0.##}): +{6:0.##%}"
                    + Environment.NewLine + "    Talents/Effects: +{11:0.##%}"
                    + Environment.NewLine
                    + Environment.NewLine + "Force Chance to Crit {7:#0.##%}"
                    + Environment.NewLine + "Base: {1:#0.##%}"
                    + Environment.NewLine + "Bonus: {8:#0.##%}"
                    + Environment.NewLine + "    Strength ({3:#,##0.##}): +{4:#0.##%}"
                    + Environment.NewLine + "    Willpower ({9:#,##0.##}): +{10:#0.##%}"
                    + Environment.NewLine + "    Critical Rating ({5:#,##0.##}): +{6:0.##%}"
                    + Environment.NewLine + "    Talents/Effects: +{12:0.##%}"
                    +                       "*Chance that a successful attack will deal"
                    + Environment.NewLine + "critical damage."
                    ,
                    /*00*/AverageStats.BonusCritChance + AverageStats.BonusBasicCritChance,
                    /*01*/0.05f,
                    /*02*/AverageStats.BonusCritChance + AverageStats.BonusBasicCritChance - 0.05f,
                    /*03*/AverageStats.Strength, /*04*/StatConversion.GetCritFromMainStat(AverageStats.Strength),
                    /*05*/AverageStats.CritRating, /*06*/StatConversion.GetCritFromRating(AverageStats.CritRating),
                    /*07*/AverageStats.BonusCritChance + AverageStats.BonusForceCritChance,
                    /*08*/AverageStats.BonusCritChance + AverageStats.BonusForceCritChance - 0.05f,
                    /*09*/AverageStats.Willpower, /*10*/StatConversion.GetCritFromSecStat(AverageStats.Willpower),
                    /*11*/AverageStats.BonusBasicCritChance,
                    /*12*/AverageStats.BonusForceCritChance - StatConversion.GetCritFromSecStat(AverageStats.Willpower)
                    );
                dictValues["Chance to Crit"] = statement + "*" + tooltip;
            }
            dictValues["Chance to Hit"] = string.Format("{0:0.00%}",
                Math.Max(0f, 1f - DodgedAttacks - ParriedAttacks - MissedAttacks - 0f
                                - (AverageStats.BonusCritChance + AverageStats.BonusBasicCritChance)));
            #endregion
            #region Offensive Stats
            dictValues["Power"] = string.Format("{0}", AverageStats.Power);
            dictValues["Force Power"] = string.Format("{0}", AverageStats.ForcePower);
            dictValues["Accuracy"] = string.Format("{0:0.00%}*Accuracy Rating {1}", Accuracy, AverageStats.AccuracyRating);
            dictValues["Alacrity"] = string.Format("{0:0.00%}*Alacrity Rating {1:0.00}", AlacrityPercent, AverageStats.AlacrityRating);
            dictValues["Avoided Attacks"] = string.Format("{0:0.00%}", AvoidedAttacks);
            dictValues["Total DPS"] = string.Format("{0:0.0}", TotalDPS);
            dictValues["Total TPS"] = string.Format("{0:0.0}", TotalTPS);
            dictValues["Rotation"] = "See Tooltip*" + Rot.GCDUsage;
            #endregion
            #region Offensive Abilities
            Dictionary<Type, bool> TypeWasDone = new Dictionary<Type, bool>();
            foreach (Type t in CalculationOptionsPanelJuggernaut.RelevantClassAbilityTpes) { TypeWasDone[t] = false; }
            foreach (AbilityWrapper aw in Rot.TheAbilityList)
            {
                TypeWasDone[aw.Ability.GetType()] = true;
                int c = 0;
                string nf = "#,##0.##", pf = "#,##0.##%";
                float adou = aw.Ability.DamageOnUseOverride;
                float atou = adou * (1f + AverageStats.ThreatIncreaseMultiplier + aw.Ability.DamageCoreThreatMod[1] /*+ (aw.Ability.HighThreat ? 0.50f : 0f)*/) * (1f - AverageStats.ThreatReductionMultiplier);
                float ahou = aw.Ability.HealingOnUse;
                //string statement = string.Format("D:{"+c+++":"+nf+"} T:{"+c+++":"+nf+"} H:{"+c+++":"+nf+"}", aw.AllDPS, aw.AllTPS, aw.AllHPS);
                string statement = string.Format("{"+c+++":"+"0000"+"} : {"+c+++":"+"0000"+"} : {"+c+++":"+"000.00"+"}", aw.AllDPS, adou, aw.AllNumActivates);
                c = 0;
                string tooltip = string.Format("{"+c+++"}"
                    + Environment.NewLine + "*Used {"+c+++":"+nf+"} Times = Opn: {"+c+++":"+nf+"} + O20: {"+c+++":"+nf+"} + U20: {"+c+++":"+nf+"}"
                    + Environment.NewLine
                    + Environment.NewLine + "DPS: {"+c+++":"+nf+"} = Opn: {"+c+++":"+nf+"} + O20: {"+c+++":"+nf+"} + U20: {"+c+++":"+nf+"}"
                    + Environment.NewLine + "Average Damage on Use: {"+c+++":"+nf+"}"
                    + Environment.NewLine
                    + Environment.NewLine + "TPS: {"+c+++":"+nf+"} = Opn: {"+c+++":"+nf+"} + O20: {"+c+++":"+nf+"} + U20: {"+c+++":"+nf+"}"
                    + Environment.NewLine + "Average Threat on Use: {"+c+++":"+nf+"}"
                    + Environment.NewLine
                    + Environment.NewLine + "HPS: {"+c+++":"+nf+"} = Opn: {"+c+++":"+nf+"} + O20: {"+c+++":"+nf+"} + U20: {"+c+++":"+nf+"}"
                    + Environment.NewLine + "Average Healing on Use: {"+c+++":"+nf+"}"
                    + Environment.NewLine
                    + Environment.NewLine + "Resource Consumption: {"+c+++":"+nf+"} = Opn: {"+c+++":"+nf+"} + O20: {"+c+++":"+nf+"} + U20: {"+c+++":"+nf+"}"
                    + Environment.NewLine + "Average Resource Consumption on Use: {"+c+++":"+nf+"}"
                    + Environment.NewLine + "Average Damage Per Resource Consumed on Use: {"+c+++":"+nf+"}"
                    + Environment.NewLine
                    + Environment.NewLine + "Attack Table:"
                    + Environment.NewLine + "    Dodge: {"+c+++":"+pf+"}"
                    + Environment.NewLine + "    Parry: {"+c+++":"+pf+"}"
                    + Environment.NewLine + "    Miss: {"+c+++":"+pf+"}"
                    + Environment.NewLine + "    Shield: {"+c+++":"+pf+"}"
                    + Environment.NewLine + "    Crit: {"+c+++":"+pf+"}"
                    + Environment.NewLine + "    Hit: {"+c+++":"+pf+"}"
                    + Environment.NewLine + "    Table Size: {"+c+++":"+pf+"}"
                    ,
                    aw.Ability.Name + (aw.IsDamaging ? " [Does Damage]" : ""),
                    aw.AllNumActivates, aw.NumActivatesOpener, aw.NumActivatesO20, aw.NumActivatesU20,
                    aw.AllDPS, aw.DPS_Opener, aw.DPS_O20, aw.DPS_U20,
                    adou,
                    aw.AllTPS, aw.TPS_Opener, aw.TPS_O20, aw.TPS_U20,
                    atou,
                    aw.AllHPS, aw.HPS_Opener, aw.HPS_O20, aw.HPS_U20,
                    ahou,
                    aw.AllResource, aw.ResourceOpener, aw.ResourceO20, aw.ResourceU20,
                    (aw.Ability.ResourceCost == 0 ? "None" : (aw.Ability.ResourceCost < 0 ? (Math.Abs(aw.Ability.ResourceCost) + " Gained") : (aw.Ability.ResourceCost + "Used"))),
                    aw.Ability.ResourceCost <= 0 ? "None" : (adou / aw.Ability.ResourceCost).ToString(),
                    aw.Ability.MHAtkTable.Dodge,
                    aw.Ability.MHAtkTable.Parry,
                    aw.Ability.MHAtkTable.Miss,
                    aw.Ability.MHAtkTable.Shield,
                    aw.Ability.MHAtkTable.Crit,
                    aw.Ability.MHAtkTable.Hit,
                    aw.Ability.MHAtkTable.Dodge + aw.Ability.MHAtkTable.Parry + aw.Ability.MHAtkTable.Miss
                        + aw.Ability.MHAtkTable.Shield + aw.Ability.MHAtkTable.Crit + aw.Ability.MHAtkTable.Hit
                    );
                dictValues[aw.Ability.Name] = statement + "*" + tooltip;
            }
            CollectedCharacterJuggernaut collChar = null;
            foreach (KeyValuePair<Type, bool> kvp in TypeWasDone)
            {
                if (kvp.Value) { continue; } // Was done in the Ability Wrapper foreach
                //if (collChar == null) {
                    collChar = new CollectedCharacterJuggernaut()
                    {
                        CombatFactors = CombatFactors,
                        Rotation = Rot,
                        BossOpts = CombatFactors.BossOpts,
                        Char = CombatFactors.Char,
                        CalcOpts = CombatFactors.CalcOpts as CalculationOptionsJuggernaut,
                        DefendModel = DefendModel,
                    };
                //}
                AbilityWrapper aw = new AbilityWrapper((ClassAbility)Activator.CreateInstance(kvp.Key, collChar));
                dictValues[aw.Ability.Name] = "Not Used in Rotation";
            }
            #endregion
            #region Resistances
            dictValues["Kinetic Resist"]   = string.Format("{0:0}*{1:0.00%} Total Reduction in Defensive Stance", AverageStats.KineticResistance, KineticReduction);
            dictValues["Energy Resist"]    = string.Format("{0:0}*{1:0.00%} Total Reduction in Defensive Stance", AverageStats.EnergyResistance, EnergyReduction);
            dictValues["Internal Resist"]  = string.Format("{0:0}*{1:0.00%} Total Reduction in Defensive Stance", AverageStats.InternalResistance, InternalReduction);
            dictValues["Elemental Resist"] = string.Format("{0:0}*{1:0.00%} Total Reduction in Defensive Stance", AverageStats.ElementalResistance, ElementalReduction);
            dictValues["Elemental Survival"] = ElementalSurvivalPoints.ToString();
            dictValues["Internal Survival"] = InternalSurvivalPoints.ToString();
            dictValues["Energy Survival"] = EnergySurvivalPoints.ToString();
            dictValues["Kinetic Survival"] = KineticSurvivalPoints.ToString();
            #endregion
            #region Complex Stats
            switch (RankingMode)
            {
                case 3:
                    dictValues["Ranking Mode"] = "Burst Time*The average amount of time between events which have a chance to result in a burst death";
                    dictValues["Survival Points"] = string.Format("{0:0}*{1:0.00} seconds between events", SurvivalPoints, SurvivalPoints / 100.0f);
                    break;
                case 4:
                    dictValues["Ranking Mode"] = "Damage Output*The average amount of DPS which can be produced";
                    dictValues["Survival Points"] = string.Format("{0:0}*Survival is not weighted in this mode", SurvivalPoints, SurvivalPoints / 100.0f);
                    break;
                default:
                    dictValues["Ranking Mode"] = "Mitigation Scale*Default scale which compares mitigation, effective health, and threat.";
                    dictValues["Survival Points"] = string.Format("{0:0}*Effective Health", SurvivalPoints);
                    break;
            }
            dictValues["Overall Points"] = string.Format("{0:0}", OverallPoints);
            dictValues["Mitigation Points"] = string.Format("{0:0}", MitigationPoints);
            dictValues["Threat Points"] = string.Format("{0:0}", ThreatPoints);
            #endregion

            return dictValues;
        }

        public override float GetOptimizableCalculationValue(string calculation)
        {
            switch (calculation)
            {
                case "Health": return AverageStats.Health;
                
                case "% Total Mitigation": return TotalMitigation * 100.0f;
                case "% Guaranteed Reduction": return GuaranteedReduction * 100.0f;
                case "% Chance to be Crit": return ((float)Math.Round(CritVulnerability * 100.0f, 2));
                case "% Avoidance": return AnyMiss * 100.0f;
                case "% Avoidance+Shield": return AnyAvoid * 100.0f;

                case "Threat/sec": return TotalTPS;
                case "% Chance to be Avoided": return AvoidedAttacks * 100.0f;
                case "% Chance to be Parried": return ParriedAttacks * 100.0f;
                case "% Chance to be Dodged": return DodgedAttacks * 100.0f;
                case "% Chance to Miss": return MissedAttacks * 100.0f;
                
                case "Burst Time": return BurstTime;
                case "Elemental Survival": return ElementalSurvivalPoints;
                case "Energy Survival": return EnergySurvivalPoints;
                case "Internal Survival": return InternalSurvivalPoints;
                case "Kinetic Survival": return KineticSurvivalPoints;
            }
            return 0.0f;
        }
    }
}